<template>
  <el-container style="padding: 20px">
    <el-header style="margin-bottom: 20px; font-size: 24px">图片管理</el-header>

    <!-- 上传组件 -->
    <el-card shadow="always" style="margin-bottom: 20px">
      <el-upload
        action="/api/generalData/upload"
        :headers="uploadHeaders"
        :on-success="handleUploadSuccess"
        name="file"
        list-type="picture"
        accept="image/*">
        <el-button type="primary">上传图片</el-button>
      </el-upload>
    </el-card>

    <!-- 显示开关 -->
    <el-checkbox v-model="showImages" label="允许渲染图片" size="large" style="margin-bottom: 20px" />

    <!-- 图片列表 -->
    <el-row :gutter="20">
      <el-col v-for="img in images" :key="img.id" :span="6">
        <el-card shadow="hover" style="margin-bottom: 20px">
          <div v-if="showImages">
            <div v-if="img.loadComplete">
              <img :src="`data:image/jpeg;base64,${img.imageBytes}`" alt="预览" width="100%" />
            </div>
            <div v-else-if="img.loading" class="image-placeholder">
              加载中...
            </div>
            <div v-else class="image-placeholder">
              <el-button @click="loadImageBytes(img)" size="small">加载图片</el-button>
            </div>
          </div>

          <div v-else class="image-placeholder">
            <el-icon name="picture"></el-icon>
          </div>

          <div style="margin-top: 10px;">
            <el-input v-model="img.description" size="small" @change="updateDescription(img)" placeholder="描述" />
          </div>

          <div style="margin-top: 10px;">
            <el-button size="small" @click="downloadImage(img)">下载图片</el-button>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </el-container>
</template>


<script setup>
import { ref, onMounted } from 'vue'
import axios from '@/utils/axios'
import {useUserStore} from "@store/userStore.js";

const showImages = ref(true)
const images = ref([])
const uploadHeaders = {
  Authorization: `Bearer ${useUserStore().token}`
}

// 获取所有图片数据
async function fetchImages() {
  const res = await axios.get('/api/generalData/getAllImage')
  images.value = res.data.map(i => ({ ...i, editing: false,loadComplete:false,loading:false }))
  if(showImages.value){
    for (const i of images.value) {
      await loadImageBytes(i);
    }
  }
}

// 上传成功回调
function handleUploadSuccess(response) {
  fetchImages()
}

// 更新描述
async function updateDescription(img) {
  await axios.put('/api/image/update', null, {
    params: {
      id: img.id,
      description: img.description
    }
  })
  ElMessage.success('描述已更新')
}

// 下载图片
function downloadImage(img) {
  const blob = new Blob([base64ToArrayBuffer(img.imageBytes)], { type: 'image/jpeg' });
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = `${img.description || 'image'}.jpg`;
  link.click();
  URL.revokeObjectURL(link.href);
}
// 懒加载图片字节
async function loadImageBytes(img) {
  img.loading = true
  try {
    const res = await axios.get(`/api/generalData/getImage/${img.id}`, {
      responseType: 'arraybuffer'
    })
    img.imageBytes = arrayBufferToBase64(res);
    img.loadComplete = true;
  } finally {
    img.loading = false;
  }
}
// Base64 转 ArrayBuffer
function base64ToArrayBuffer(base64) {
  const binaryString = window.atob(base64);
  const len = binaryString.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  return bytes.buffer;
}

// ArrayBuffer 转 Base64
function arrayBufferToBase64(arrayBuffer) {
  return btoa(new Uint8Array(arrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), ''));
}

onMounted(async () => {
  await fetchImages()
})
</script>

<style scoped>

.image-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 150px;
  background-color: #f9fafb;
  border: 1px dashed #dcdfe6;
  color: #999;
  font-size: 16px;
}
</style>
